home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / iswait.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  4.7 KB  |  160 lines

  1. /* iswait.c
  2.    Wait for a process to finish.
  3.  
  4.    Copyright (C) 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "sysdep.h"
  30.  
  31. #include <errno.h>
  32.  
  33. #if HAVE_SYS_WAIT_H
  34. #include <sys/wait.h>
  35. #endif
  36.  
  37. /* We use a typedef wait_status for wait (waitpid, wait4) to put
  38.    results into.  We define the POSIX examination functions we need if
  39.    they are not already defined (if they aren't defined, I assume that
  40.    we have a standard wait status).  */
  41.  
  42. #if HAVE_UNION_WAIT
  43. typedef union wait wait_status;
  44. #ifndef WIFEXITED
  45. #define WIFEXITED(u) ((u).w_termsig == 0)
  46. #endif
  47. #ifndef WEXITSTATUS
  48. #define WEXITSTATUS(u) ((u).w_retcode)
  49. #endif
  50. #ifndef WTERMSIG
  51. #define WTERMSIG(u) ((u).w_termsig)
  52. #endif
  53. #else /* ! HAVE_UNION_WAIT */
  54. typedef int wait_status;
  55. #ifndef WIFEXITED
  56. #define WIFEXITED(i) (((i) & 0xff) == 0)
  57. #endif
  58. #ifndef WEXITSTATUS
  59. #define WEXITSTATUS(i) (((i) >> 8) & 0xff)
  60. #endif
  61. #ifndef WTERMSIG
  62. #define WTERMSIG(i) ((i) & 0x7f)
  63. #endif
  64. #endif /* ! HAVE_UNION_WAIT */
  65.  
  66. /* Wait for a particular process to finish.  The ipid argument should
  67.    be pid_t, but then we couldn't have a prototype.  If the zreport
  68.    argument is not NULL, then a wait error will be logged, and if the
  69.    exit status is non-zero it will be logged with zreport as the
  70.    header of the log message.  If the zreport argument is NULL, no
  71.    errors will be logged.  This function returns the exit status if
  72.    the process exited normally, or -1 on error or if the process was
  73.    killed by a signal (I don't just always return the exit status
  74.    because then the calling code would have to prepared to handle
  75.    union wait status vs. int status, and none of the callers care
  76.    which signal killed the program anyhow).
  77.  
  78.    This functions keeps waiting until the process finished, even if it
  79.    is interrupted by a signal.  I think this is right for all uses.
  80.    The controversial one would be when called from uuxqt to wait for a
  81.    requested process.  Hitting uuxqt with SIGKILL will approximate the
  82.    actions taken if we return from here with an error anyhow.  If we
  83.    do get a signal, we call ulog with a NULL argument to get it in the
  84.    log file at about the right time.  */
  85.  
  86. int
  87. ixswait (ipid, zreport)
  88.      unsigned long ipid;
  89.      const char *zreport;
  90. {
  91.   wait_status istat;
  92.  
  93. #if HAVE_WAITPID
  94.   while (waitpid ((pid_t) ipid, (pointer) &istat, 0) < 0)
  95.     {
  96.       if (errno != EINTR)
  97.     {
  98.       if (zreport != NULL)
  99.         ulog (LOG_ERROR, "waitpid: %s", strerror (errno));
  100.       return -1;
  101.     }
  102.       ulog (LOG_ERROR, (const char *) NULL);
  103.     }
  104. #else /* ! HAVE_WAITPID */
  105. #if HAVE_WAIT4
  106.   while (wait4 ((pid_t) ipid, (pointer) &istat, 0,
  107.         (struct rusage *) NULL) < 0)
  108.     {
  109.       if (errno != EINTR)
  110.     {
  111.       if (zreport != NULL)
  112.         ulog (LOG_ERROR, "wait4: %s", strerror (errno));
  113.       return -1;
  114.     }
  115.       ulog (LOG_ERROR, (const char *) NULL);
  116.     }
  117. #else /* ! HAVE_WAIT4 */
  118.   pid_t igot;
  119.  
  120.   /* We could theoretically get the wrong child here if we're in some
  121.      kind of weird pipeline, so we don't give any error messages for
  122.      it.  */
  123.   while ((igot = wait ((pointer) &istat)) != (pid_t) ipid)
  124.     {
  125.       if (igot < 0)
  126.     {
  127.       if (errno != EINTR)
  128.         {
  129.           if (zreport != NULL)
  130.         ulog (LOG_ERROR, "wait: %s", strerror (errno));
  131.           return -1;
  132.         }
  133.       ulog (LOG_ERROR, (const char *) NULL);
  134.     }
  135.     }
  136. #endif /* ! HAVE_WAIT4 */
  137. #endif /* ! HAVE_WAITPID */  
  138.  
  139.   DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d",
  140.           WIFEXITED (istat) ? "Exit status" : "Signal",
  141.           WIFEXITED (istat) ? WEXITSTATUS (istat) : WTERMSIG (istat));
  142.  
  143.   if (WIFEXITED (istat) && WEXITSTATUS (istat) == 0)
  144.     return 0;
  145.  
  146.   if (zreport != NULL)
  147.     {
  148.       if (! WIFEXITED (istat))
  149.     ulog (LOG_ERROR, "%s: Got signal %d", zreport, WTERMSIG (istat));
  150.       else
  151.     ulog (LOG_ERROR, "%s: Exit status %d", zreport,
  152.           WEXITSTATUS (istat));
  153.     }
  154.  
  155.   if (WIFEXITED (istat))
  156.     return WEXITSTATUS (istat);
  157.   else
  158.     return -1;
  159. }
  160.